import PropTypes from 'prop-types';
import React from 'react';
import {compose} from 'redux';
import {connect} from 'react-redux';
import ReactModal from 'react-modal';

import {getIsError,getIsShowingProject, getIsFetchingWithId, getIsLoadingWithId} from '../reducers/project-state';
import {activateTab,BLOCKS_TAB_INDEX,COSTUMES_TAB_INDEX,SOUNDS_TAB_INDEX} from '../reducers/editor-tab';
import {closeMyProjectLibrary, closeYxProjectLibrary, closeCostumeLibrary,closeBackdropLibrary,openExtensionLibrary} from '../reducers/modals';
import {showStandardAlert, closeStandardAlert} from '../reducers/alerts';

//import LocalizationHOC from '../lib/localization-hoc.jsx';
import ErrorBoundaryHOC from '../lib/error-boundary-hoc.jsx';
import FontLoaderHOC from '../lib/font-loader-hoc.jsx';
import ProjectFetcherHOC from '../lib/project-fetcher-hoc.jsx';
import ProjectSaverHOC from '../lib/project-saver-hoc.jsx';
import vmListenerHOC from '../lib/vm-listener-hoc.jsx';
import vmManagerHOC from '../lib/vm-manager-hoc.jsx';
import cloudManagerHOC from '../lib/cloud-manager-hoc.jsx';

import storage from '../lib/storage';
import GUIComponent from '../components/gui/gui.jsx';
class GUI extends React.Component {
    componentDidMount () {
        this.props.onStorageInit(storage);//初始化资源路径
        //this.props.onVmInit(this.props.vm);
    }
    render () {
        if (this.props.isError) {throw new Error(`Error in Scratch GUI [location=${window.location}]: ${this.props.error}`);}

        const {
            /* eslint-disable no-unused-vars */
            //onVmInit,
            onStorageInit,

            isError,
            error,

            isFetchingWithId,
            isLoadingWithId,
            loadingStateVisible,

            //children,
            /* eslint-enable no-unused-vars */

            ...componentProps
        } = this.props;

        return (
            <GUIComponent
                loading={isFetchingWithId || isLoadingWithId || loadingStateVisible}
                {...componentProps}
            >
                {/*children*/}
            </GUIComponent>
        );
    }
}
//验证父组件传值的合法性
GUI.propTypes = {
    onStorageInit: PropTypes.func,
    //onVmInit: PropTypes.func,
    //vm: PropTypes.instanceOf(VM).isRequired,

    isError: PropTypes.bool,
    error: PropTypes.oneOfType([PropTypes.object, PropTypes.string]),

    isFetchingWithId: PropTypes.bool,
    isLoadingWithId: PropTypes.bool,

    loadingStateVisible: PropTypes.bool,
    //children: PropTypes.node,
};

//父组件传递的默认值，如果父组件不传递值，则用此处的默认值。
GUI.defaultProps = {
    onStorageInit: storageInstance => storageInstance.addOfficialScratchWebStores(),
    //onVmInit: (/* vm */) => {}
};

const mapStateToProps = state => {
    const loadingState = state.project.loadingState;
    return {
        //vm: state.scratchGui.vm,
        isError: getIsError(loadingState),
        error: state.project.error,

        isFetchingWithId: getIsFetchingWithId(state.project.loadingState),//判断是否需要继续显示加载界面的参数之一
        isLoadingWithId: getIsLoadingWithId(loadingState),//判断是否需要继续显示加载界面的参数之一
        loadingStateVisible: state.scratchGui.modals.loadingProject,//判断是否需要继续显示加载界面的参数之一

        isFullScreen: state.scratchGui.mode.isFullScreen,//点击全屏时

        activeTabIndex: state.scratchGui.editorTab.activeTabIndex,
        blocksTabVisible: state.scratchGui.editorTab.activeTabIndex === BLOCKS_TAB_INDEX,
        soundsTabVisible: state.scratchGui.editorTab.activeTabIndex === SOUNDS_TAB_INDEX,
        costumesTabVisible: state.scratchGui.editorTab.activeTabIndex === COSTUMES_TAB_INDEX,

        backdropLibraryVisible: state.scratchGui.modals.backdropLibrary, // 背景选择界面
        myProjectLibraryVisible: state.scratchGui.modals.myProjectLibrary, // 我的作品
        yxProjectLibraryVisible: state.scratchGui.modals.yxProjectLibrary, // 优秀作品



        connectionModalVisible: state.scratchGui.modals.connectionModal,
        costumeLibraryVisible: state.scratchGui.modals.costumeLibrary,
     
        targetIsStage: (
            state.scratchGui.targets.stage &&
            state.scratchGui.targets.stage.id === state.scratchGui.targets.editingTarget
        ),

        
        //alertsList: state.scratchGui.alerts.alertsList,
        //alertsVisible: (state.scratchGui.alerts.alertsList.length==0)?false:true,
    };
};

const mapDispatchToProps = dispatch => ({
    onExtensionButtonClick: () => dispatch(openExtensionLibrary()),
    onActivateTab: tab => dispatch(activateTab(tab)),
    onActivateCostumesTab: () => dispatch(activateTab(COSTUMES_TAB_INDEX)),
    onActivateSoundsTab: () => dispatch(activateTab(SOUNDS_TAB_INDEX)),
    onRequestCloseBackdropLibrary: () => dispatch(closeBackdropLibrary()),
    onRequestCloseCostumeLibrary: () => dispatch(closeCostumeLibrary()),
    
    onRequestCloseMyProjectLibrary: () => dispatch(closeMyProjectLibrary()),
    onRequestCloseYxProjectLibrary: () => dispatch(closeYxProjectLibrary())
    //onCloseAlert: () => dispatch(closeStandardAlert())
});

const ConnectedGUI = connect(
    mapStateToProps,
    mapDispatchToProps,
)(GUI);

// note that redux's 'compose' function is just being used as a general utility to make
// the hierarchy of HOC constructor calls clearer here; it has nothing to do with redux's
// ability to compose reducers.
const WrappedGui = compose(
    ErrorBoundaryHOC('Top Level App'),
    FontLoaderHOC,
    ProjectFetcherHOC,
    ProjectSaverHOC,
    vmListenerHOC,
    vmManagerHOC,
    cloudManagerHOC
)(ConnectedGUI);

WrappedGui.setAppElement = ReactModal.setAppElement;
export default WrappedGui;
